#pragma once 
extern "C"
#include<stdint.h>
class Des{
public:
	//构造函数
	Des(void);
	//生成初始密钥
	uint64_t generateKey(void) const;
	//加密
	int encrypt(uint64_t key,const void * mbuf,size_t mlen,void *cbuf,size_t* clen) const;
	//解密
	int decrypt(uint64_t key,const void * cbuf,size_t clen,void *mbuf,size_t* mlen) const;
private:
	//校验初始密钥
	int verifykey(uint64_t K0) const;
	//置换选择PC1
	void PC1(uint64_t K0,uint32_t *C,uint32_t *D) const;
	//循环左移
	void LS(int iKey,uint32_t *C,uint32_t *D) const;
	//置换选择PC2
	uint64_t PC2(uint32_t C,uint32_t D) const;
	//生成子密钥
	void generateRoundKeys(uint64_t K0,uint64_t *roundKeys) const;
	//选择扩展运算
	uint64_t E(uint32_t R) const;
	//密钥加运算
	uint64_t X(uint64_t R,uint64_t K) const;
	//选择压缩运算
	uint32_t S(uint64_t R) const;
	//置换运算
	uint32_t P(uint32_t R) const;
	//加密变幻
	uint32_t F(uint32_t R,uint64_t K) const;
	//初始置换
	void IP(uint64_t M,uint32_t *L,uint32_t *R) const;
	//16轮迭代
	void R16(const uint64_t *rountKeys,uint32_t *L,uint32_t *R) const; 
	//逆初始置换
	uint64_t IIP(uint32_t L,uint32_t R) const;
	//加密分组
	uint64_t M2C(const uint64_t *roundKeys,uint64_t M) const;
	//解密分组
	uint64_t C2M(const uint64_t *roundKeys,uint64_t C) const;

	static const uint8_t pc1[2][28];//置换选择表1
	static const uint8_t ls[16];//置换左移表
	static const uint8_t pc2[48];//置换选择表2

	static const uint8_t ip[64];//初使置换表
	static const uint8_t e[48];//扩展变幻表
	static const uint8_t s[8][64];//压缩变幻表
	static const uint8_t p[32];//置换变幻表
	static const uint8_t iip[64];//逆初始置换表
	
	uint32_t bm32[32];//32位位掩码表
	uint64_t bm64[64];//64位位掩码表
	

};
